﻿using I3.AgenteIA.Dominio.Gramatica;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Moq;
using System.Collections.Generic;
using System.Collections;
using System.Linq;


namespace I3.AgenteIA.Dominio.Teste
{
    [TestClass()]
    public class ElementoInterpreterTest
    {
        /// <summary>
        /// Armazena os finalizadores usados no teste
        /// </summary>
        private IEnumerable<Sinal> finalizadores = new Sinal[] { 
                new Sinal(".") { EhFinalizador = false }, 
                new Sinal("!") { EhFinalizador = false },
                new Sinal("?") { EhFinalizador = false } };

        [TestMethod()]
        public void InterpretarTest_Caso0()
        {
            var oracao = new Mock<Oracao>();
            InterpretarTest_Execucao(new Sentenca(oracao.Object, "!"), new List<Elemento>(new Elemento[]{ 
                new Elemento("!") 
            }));
        }

        [TestMethod()]
        public void InterpretarTest_Caso1()
        {
            var oracao = new Mock<Oracao>();
            InterpretarTest_Execucao(new Sentenca(oracao.Object, "Simples"), new List<Elemento>(new Elemento[] { 
                new Elemento("Simples") 
            }));
        }

        [TestMethod()]
        public void InterpretarTest_Caso2()
        {
            var oracao = new Mock<Oracao>();
            InterpretarTest_Execucao(new Sentenca(oracao.Object, "Simples!"), new List<Elemento>(new Elemento[] { 
                new Elemento("Simples"), 
                new Elemento("!") 
            }));
        }

        [TestMethod()]
        public void InterpretarTest_Caso3()
        {
            var oracao = new Mock<Oracao>();
            InterpretarTest_Execucao(new Sentenca(oracao.Object, "Simples!!!"), new List<Elemento>(new Elemento[] { 
                new Elemento("Simples"), 
                new Elemento("!"), new Elemento("!"), new Elemento("!")
            }));
        }

        [TestMethod()]
        public void InterpretarTest_Caso4()
        {
            var oracao = new Mock<Oracao>();
            InterpretarTest_Execucao(new Sentenca(oracao.Object, "frase composta"), new List<Elemento>(new Elemento[] { 
                new Elemento("frase"), 
                new Elemento("composta") 
            }));
        }

        [TestMethod()]
        public void InterpretarTest_Caso5()
        {
            var oracao = new Mock<Oracao>();
            InterpretarTest_Execucao(new Sentenca(oracao.Object, "frase composta?"), new List<Elemento>(new Elemento[] { 
                new Elemento("frase"), 
                new Elemento("composta"),
                new Elemento("?") 
            }));
        }

        [TestMethod()]
        public void InterpretarTest_Caso6()
        {
            var oracao = new Mock<Oracao>();
            InterpretarTest_Execucao(new Sentenca(oracao.Object, "frase composta???"), new List<Elemento>(new Elemento[] { 
                new Elemento("frase"), 
                new Elemento("composta"),
                new Elemento("?"),new Elemento("?"),new Elemento("?") 
            }));
        }

        [TestMethod()]
        public void InterpretarTest_Caso7()
        {
            var oracao = new Mock<Oracao>();
            InterpretarTest_Execucao(new Sentenca(oracao.Object, "frase com endereço@email.com"), new List<Elemento>(new Elemento[] { 
                new Elemento("frase"), 
                new Elemento("com"),
                new Elemento("endereço@email.com") 
            }));
        }

        [TestMethod()]
        public void InterpretarTest_Caso8()
        {
            var oracao = new Mock<Oracao>();
            InterpretarTest_Execucao(new Sentenca(oracao.Object, "frase com www.endereco.com.br"), new List<Elemento>(new Elemento[] { 
                new Elemento("frase"), 
                new Elemento("com"),
                new Elemento("www.endereco.com.br") 
            }));
        }


        private void InterpretarTest_Execucao(Sentenca sentenca, IEnumerable<Elemento> elementosEsperados)
        {
            // Declara as variaveis auxiliares do teste

            // Declara os objetos mock do teste
            var repositorio = new Mock<IRepositorioGramatica>();

            // Configura a execução dos métodos mock

            // Realizada a execução do teste
            ElementoInterpreter servico = new ElementoInterpreter(repositorio.Object);
            IEnumerable<Elemento> elementosAtuais = servico.Interpretar(sentenca);

            // Realiza os assets dos objetos mocks e variaveis
            Assert.IsNotNull(elementosAtuais);
            Assert.AreEqual(elementosEsperados.Count(), elementosAtuais.Count());
            for (int i = 0, total = elementosAtuais.Count(); i < total; i++)
                Assert.AreEqual(elementosEsperados.ElementAt(i).Texto,
                    elementosAtuais.ElementAt(i).Texto);
            
        }
    }
}
